
%MACRO compute_events (in,out);

*****************************************************************************
* Program: COMPUTE_EVENT					   						
* 																			
* Description: Computes drug use and opiate-free time and events
*				given varying conditions;
*						
* Last modified: August 11, 2015												
* Created by: Martin Wegman													
*****************************************************************************;

%let dat = data; * Dataset name stem;

%let v = 26; * From patterns sas file;

data loc.&dat.&v;
	set loc.&in;
run;

****************************************************************************;
****************************************************************************;
*********     Compute drug use and opiate free time       ******************;
****************************************************************************;
****************************************************************************;

%MACRO compute_drug_free_time(v);

	%local v2;

	%let pts = 9;	

	%let v2 = %eval(&v + 1);

	%let list = opi amp bzd bup mtd hiv any;

	data loc.&dat&v2;
		set loc.&dat&v;
	run;

	%do i = 1 %to 7;

		%let var = %scan(&list, &i);
		%put &var;

		data loc.&dat&v2;
			set loc.&dat&v2;

			array Y [*] Y0_&var Y1_&var Y2_&var Y3_&var 
						Y4_&var Y6_&var Y9_&var Y12_&var Y15_&var;

			i = 1;
			n =0;
			d =0;

			do until (i > 9);

				if Y[i] = 1 then d = d + 1;
				if Y[i] = 0 then do;
					d = d + 1;
					n = n + 1; 
				end;
				i = i + 1;
			end;

			if n = 0 then n = .;

			p_&var = n/d;
			free_&var = T_last*p_&var;
			present_&var = T_last*(d-n)/d;

			drop i n d;
		run;

	%end;

%MEND;

****************************************************************************;
%compute_drug_free_time(&v);

****************************************************************************;
****************************************************************************;
**************          Compute events           ***************************;
****************************************************************************;
****************************************************************************;

%MACRO compute_event(v,v2);

	%let pts = 9;

	%let list = opi amp bzd thc bup mtd hiv any;

	data loc.&dat&v2;
		set loc.&dat&v;
	run;

	%do i = 1 %to 8;

		%let var = %scan(&list, &i);
		%put &var;

		data loc.&dat&v2;
			set loc.&dat&v2;

			array Y [*] Y0_&var Y1_&var Y2_&var Y3_&var 
						Y4_&var Y6_&var Y9_&var Y12_&var Y15_&var;
			array T [*] T0 --T15;
			array F [*] F0 --F15;

			array times TA_&var TB_&var TC_&var TD_&var
							TE_&var TF_&var TG_&var TH_&var;

			* YA - Ignore missing;
			n = 1;

			do until (YA_&var = 1 or n > &pts);
				if Y[n] = 1 then do;
					YA_&var = 1;
					TA_&var = T[n];
				end;
				else if Y[n] = 0 then do;
					YA_&var = 0;
					TA_&var = T[n];
				end;
				n + 1; 
			end;

			* YB - Any missing as event;
			n = 1;

			do until (YB_&var = 1 or n > &pts);
				if Y[n] = 1 OR F[n] in(1,2) then do;
					YB_&var = 1;
					TB_&var = T[n];
				end;
				else if Y[n] = 0 then do;
					YB_&var = 0;
					TB_&var = T[n];
				end;
				n + 1;
			end;

			* YC - Any missing as non-event;
			n = 1;

			do until (YC_&var = 1 or n > &pts);
				if Y[n] = 1 then do;
					YC_&var = 1;
					TC_&var = T[n];
				end;
				else if Y[n] = 0 OR F[n] in(1,2) then do;
					YC_&var = 0;
					TC_&var = T[n];
				end;
				n + 1;
			end;

			* YD - Worst case scenario;
			* if site = 1 then treat missing as non-event;
			n = 1;

			if site = 1 then do;
				do until (YD_&var = 1 or n > &pts);
					if Y[n] = 1 then do;
						YD_&var = 1;
						TD_&var = T[n];
					end;
					else if Y[n] = 0 OR F[n] in(1,2) then do;
						YD_&var = 0;
						TD_&var = T[n];
					end;
					n + 1;
				end;
			end;

			* if site = 2 then treat missing as event;
			else do;
				do until (YD_&var = 1 or n > &pts);
					if Y[n] = 1 OR F[n] in(1,2) then do;
						YD_&var = 1;
						TD_&var = T[n];
					end;
					else if Y[n] = 0 then do;
						YD_&var = 0;
						TD_&var = T[n];
					end;
					n + 1;
				end;
			end;


			* YE - Missing equivalent to censored;
			n = 1;
			flag = 0;

			do until (flag = 1 or n > &pts);
				if F[n] in(1,2) then do;
					YE_&var = 0;
					TE_&var = T[n];
					flag = 1;
				end;
				else if Y[n] = 1 then do;
					YE_&var = 1;
					TE_&var = T[n];
					flag = 1;
				end;
				else do;
					YE_&var = 0;
					TE_&var = T[n];
				end;
				n + 1;
			end;

			* YF - intervening missing a non-event/trailing missing an event;
			n = 1;

			do until (YF_&var = 1 or n > &pts);

				if T[n] > T_last and F[n] in (1,2) then do; * If after last observation;
					YF_&var = 1;
					TF_&var = T[n];
				end;
				else if Y[n] = 1 then do;
					YF_&var = 1;
					TF_&var = T[n];
				end;
				else do;
					YF_&var = 0;
					TF_&var = T[n];
				end;
				n + 1;
			end;

			* YG - reverse event coding mainly for methadone;
			* Missing is ignored (similar to YA);
			n = 1;

			do until (YG_&var = 1 or n > &pts);
				if Y[n] = 1 then do;
					YG_&var = 0;
					TG_&var = T[n];
				end;
				else if Y[n] = 0 then do;
					YG_&var = 1;
					TG_&var = T[n];
				end;
				n + 1; 
			end;

			* YH - Worst case scenario;
			* if site = 1 then missing has 25% chance of event;
			* if site = 2 then missing has 75% chance of event;
			n = 1;

			if site = 1 then do;
				do until (YH_&var = 1 or n > &pts);
					if Y[n] = 1 then do;
						YH_&var = 1;
						TH_&var = T[n];
					end;
					else if F[n] in(1,2) then do;
						if RAND('UNIFORM') < 0.25 
							then YH_&var = 1;
						else YH_&var = 0;
						TH_&var = T[n];
					end;
					else if Y[n] = 0 then do;
						YH_&var = 0;
						TH_&var = T[n];
					end;
					n + 1;
				end;
			end;

			* if site = 2 then treat missing as event;
			else if site = 2 then do;
				do until (YH_&var = 1 or n > &pts);
					if Y[n] = 1 then do;
						YH_&var = 1;
						TH_&var = T[n];
					end;
					else if F[n] in(1,2) then do;
						if RAND('UNIFORM') < 0.75
							then YH_&var = 1;
						else YH_&var = 0;
						TH_&var = T[n];
					end;
					else if Y[n] = 0 then do;
						YH_&var = 0;
						TH_&var = T[n];
					end;
					n + 1;
				end;
			end;


			do over times; * Events on day of release are 
								not at time zero, but between 0 and 1;
				if times = 0 then times = 0.5;
			end;

			drop n flag;

		run;

	%end;

%MEND;

****************************************************************************;

%let v = 27; 
%let v2 = %eval(&v +1);
%compute_event(&v,&v2);

data loc.&out;
	set loc.&dat.&v2;
run;

****************************************************************************;
****************************************************************************;
*********************   Remove old datasets               ******************;
****************************************************************************;
****************************************************************************;


proc datasets lib=loc nolist;       
	delete &dat.26 - &dat.28;   
run;
quit;


****************************************************************************;
****************************************************************************;
**************                END                ***************************;
****************************************************************************;
****************************************************************************;

%MEND compute_events;
